package com.umeox.watch.moto.chat.ui

import android.animation.ValueAnimator
import android.annotation.SuppressLint
import android.content.Context
import android.content.DialogInterface
import android.os.PowerManager
import android.os.PowerManager.WakeLock
import android.view.*
import android.view.GestureDetector.SimpleOnGestureListener
import android.view.View.OnTouchListener
import android.view.animation.LinearInterpolator
import android.widget.TextView
import androidx.appcompat.app.AlertDialog
import com.umeox.moto.common.log.Logger
import com.umeox.moto.common.recorder.SilentRecord
import com.umeox.moto.common.utils.FileUtils
import com.umeox.moto.watch.themes.widget.ActionBar
import com.umeox.moto.watch.themes.widget.ProgressView
import com.umeox.watch.moto.chat.R
import java.lang.Exception

/**
 * Created by Rambo 2021/8/24
 * Describe:
 */
@SuppressLint("ClickableViewAccessibility")
abstract class ChatDialog(private val context: Context, dir: String) :
    DialogInterface.OnDismissListener, SilentRecord.RecordListener {

    private lateinit var wakeLock: WakeLock
    private lateinit var recorder: SilentRecord
    private var recordCountdown: ProgressView
    private var increaseAnimator: ValueAnimator

    private  var dialog: AlertDialog
    private var tvCountDown: TextView
    private var tvRecordTip: TextView
    private var recordView: ViewGroup
    private var mAbEmoji: ActionBar
    private var mAbPhoto: ActionBar
    private var mSharePhotoView: View

    init {
        val builder: AlertDialog.Builder = AlertDialog.Builder(context)
        val rootView: View =
            LayoutInflater.from(context).inflate(R.layout.layout_choose_chat_type, null)
        mAbEmoji = rootView.findViewById(R.id.abEmoji)
        mAbPhoto = rootView.findViewById(R.id.abPhoto)
        val abVoice: ActionBar = rootView.findViewById(R.id.abVoice)
        recordView = rootView.findViewById(R.id.recordLayout)
        tvCountDown = rootView.findViewById(R.id.tvCountDown)
        tvRecordTip = rootView.findViewById(R.id.tvRecordTip)
        recordCountdown = rootView.findViewById(R.id.pvCountdown)
        mSharePhotoView = rootView.findViewById(R.id.ab_share)
        mSharePhotoView.setOnClickListener(View.OnClickListener { v: View ->
            this@ChatDialog.onClick(v)
            dismiss()
        })
        mAbEmoji.setOnClickListener { v ->
            this@ChatDialog.onClick(v)
            dismiss()
        }
        mAbPhoto.setOnClickListener { v ->
            this@ChatDialog.onClick(v)
            dismiss()
        }
        val detector = GestureDetector(context, object : SimpleOnGestureListener() {
            override fun onLongPress(e: MotionEvent) {
                startRecord()
            }
        })
        //录音图标点击弹出录音动画
        abVoice.setOnTouchListener(object : OnTouchListener {
            //Record Button on touchListener
            private var startX = 0
            private var startY = 0
            override fun onTouch(v: View, event: MotionEvent): Boolean {
                detector.onTouchEvent(event)
                when (event.action and MotionEvent.ACTION_MASK) {
                    MotionEvent.ACTION_DOWN -> {
                        startX = event.rawX.toInt()
                        startY = event.rawY.toInt()
                    }
                    MotionEvent.ACTION_MOVE -> {
                        // 获取当前x坐标
                        val currentX = event.rawX.toInt()
                        // 获取当前y坐标
                        val currentY = event.rawY.toInt()
                        // x方向移动的距离
                        val disX = currentX - startX
                        // y方向移动的距离
                        val disY = currentY - startY
                        //手指向上滑动,滑动最小距离30
                        if (disY < -40
                            && recorder.state == SilentRecord.RecorderState.STATE_RECORDING
                        ) {
                            recorder.cancelRecord()
                            FileUtils.deleteFile(recorder.recordPath)
                        }
                    }
                    MotionEvent.ACTION_UP -> stopRecord(true)
                }
                return false
            }
        })
        recordCountdown.progress = 0F
        increaseAnimator =
            ValueAnimator.ofFloat(0f, 1f).setDuration(30 * 1000L)
        increaseAnimator.interpolator = LinearInterpolator()
        increaseAnimator.addUpdateListener { animation: ValueAnimator ->
            val progress = animation.animatedValue as Float
            recordCountdown.progress = progress
            if (progress >= 1) {
                dismiss()
            }
        }
        dialog = builder.setView(rootView).create()
        recorder = SilentRecord(context, dir, 30 * 1000, this)
    }


    open fun show() {
        setEnableView(true)
        dialog.show()
    }

    private fun setEnableView(b: Boolean) {
        mAbEmoji.isEnabled = b
        mAbPhoto.isEnabled = b
        mSharePhotoView.isEnabled = b
        mSharePhotoView.visibility = if (b) View.VISIBLE else View.GONE
    }

    open fun dismiss() {
        stopRecord(false)
        dialog.dismiss()
    }

    override fun onDismiss(dialog: DialogInterface?) {
        releaseLock()
    }

    private fun startRecord() {
        //申请设备电源锁，保持屏幕常亮
        setEnableView(false)
        wakeUpAndUnlock()
        tvRecordTip.setText(R.string.slide_canel_send_tip)
        recordView.visibility = View.VISIBLE
        recorder.startRecord() //开始录音
    }

    private fun stopRecord(isUserCancel: Boolean) {
        if (recorder.state == SilentRecord.RecorderState.STATE_RECORDING
        ) {
            Logger.d("停止录音.......")
            if (isUserCancel) {
                recorder.stopRecord()
            }
        }
        recordView.visibility = View.GONE
    }

    @SuppressLint("InvalidWakeLockTag")
    private fun wakeUpAndUnlock() {
        val pm = context.getSystemService(Context.POWER_SERVICE) as PowerManager
        wakeLock = pm.newWakeLock(
            PowerManager.ACQUIRE_CAUSES_WAKEUP
                    or PowerManager.SCREEN_BRIGHT_WAKE_LOCK, "Chat Recording"
        )
        // 点亮亮屏
        wakeLock.acquire(30 * 1000L)
    }

    private fun releaseLock() {
        Logger.d("Releasing wakelock")
        try {
            wakeLock.release()
        } catch (e: Exception) {
            Logger.e("Releasing wakelock failed:$e")
        }
    }

    override fun onRecordStateChanged(
        oldState: SilentRecord.RecorderState,
        newState: SilentRecord.RecorderState
    ) {
        when (newState) {
            SilentRecord.RecorderState.STATE_IDLE -> Logger.d("Record state change to IDLE")
            SilentRecord.RecorderState.STATE_RECORDING -> Logger.d("Record state change to RECORDING")
            SilentRecord.RecorderState.STATE_RECORD_SHORT -> {
                Logger.d("Record state change to RECORD_SHORT")
                try {
                    FileUtils.deleteFile(recorder.recordPath)
                } catch (ignored: Exception) {
                }
                onRecordError(context.resources.getString(R.string.recording_short_tip))
                dismiss()
            }
            SilentRecord.RecorderState.STATE_RECORD_END -> {
                dismiss()
                val path: String = recorder.recordPath
                //直接读文件长度
                val length: Int = FileUtils.getFileDuration(path)
                if (length <= 0) {
                    return
                }
                onResult(path)
            }
            SilentRecord.RecorderState.STATE_CANCEL -> {
                Logger.d("Cancel Record By User")
                dismiss()
            }
            SilentRecord.RecorderState.STATE_ERROR -> {
                Logger.d("Record state change to ERROR")
                dismiss()
            }
            else -> {
            }
        }
    }

    override fun onRecordMicStatusUpdate(db: Int) {}

    override fun onTick(millisUntilFinished: Long) {
        if (millisUntilFinished == 30 * 1000L) {
            increaseAnimator.start()
        }
        val remainder = (millisUntilFinished / 1000).toInt()
        Logger.d("正在录音:$remainder")
        tvCountDown.text = "$remainder''"
    }

    abstract fun onClick(view: View)

    abstract fun onResult(recordFile: String)

    abstract fun onRecordError(error: String)
}
